home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / dsp / 56200tar.z / 56200tar / 56200 / p9 < prev   
Text File  |  1992-04-28  |  29KB  |  549 lines

  1.  
  2.          /***********************************************\
  3.          |**                                           **|
  4.          |**   DSP56200 CHIP DRIVER -DUAL FIR FILTERS  **|
  5.          |**                        -POLLED I/O        **|
  6.          |**                                           **|
  7.          \***********************************************/
  8.  
  9.  
  10.  
  11. /************************************************************************\
  12. *                                                                        *
  13. *   This is an example of a program located in a host processor, used    *
  14. *   to setup and service a single DSP56200 as two real-time FIR filters. *
  15. *   In this example, the host processor polls a general purpose input    *
  16. *   pin to determine the beginning of a new sample period, signified     *
  17. *   by the reception of a rising edge on the DSP56200's START pin. The   *
  18. *   general purpose input pin is tied directly to the START pin of the   *
  19. *   DSP56200.                                                            *
  20. *                                                                        *
  21. *   This program, written in the language "C", is provided only as an    *
  22. *   example, and will be much faster if translated by the user into the  *
  23. *   assembly language of the host processor.                             *
  24. *                                                                        *
  25. *                                                                        *
  26. *   The example system is configured as shown below:                     *
  27. *                                                                        *
  28. *                                                                        *
  29. *                            ------------                                *
  30. *                            | DSP56200 |                                *
  31. *                            ------------                                *
  32. *                                  ^                                     *
  33. *                                  |                                     *
  34. *                                  v                                     *
  35. *               -------    ------------------    -------                 *
  36. *      x1(t) -->| A/D |--->| Host Processor |--->| D/A |--> out1(t)      *
  37. *               -------    |                |    -------                 *
  38. *                          | (contains code |                            *
  39. *               -------    |  found in this |    -------                 *
  40. *      x2(t) -->| A/D |--->|     file)      |--->| D/A |--> out2(t)      *
  41. *               -------    ------------------    -------                 *
  42. *                                                                        *
  43. *                                                                        *
  44. *                   Figure 1. Dual FIR Filtering System                  *
  45. *                                                                        *
  46. *                                                                        *
  47. *                                                                        *
  48. *   There is only one DSP56200 in this example (i.e., not multiple       *
  49. *   DSP56200s in cascade), and it is configured in the Dual FIR Filter   *
  50. *   mode (Figure 2) by writing the DSP56200's Configuration register.    *
  51. *   Since only 16 bit  results  are sent to each D/A Converter, the      *
  52. *   outputs are rounded to 16 bits by the DSP56200.                      * 
  53. *                                                                        *
  54. *                                                                        *
  55. *                                                                        *
  56. *                                                                        *
  57. *                           --------------                               *
  58. *                           |  1st  FIR  |                               *
  59. *               x1(n) ----->|   Filter   |-----> out1(n)                 *
  60. *                           |  (7 taps)  |                               *
  61. *                           --------------                               *
  62. *                                                                        *
  63. *                           --------------                               *
  64. *                           |  2nd  FIR  |                               *
  65. *               x2(n) ----->|   Filter   |-----> out2(n)                 *
  66. *                           |  (7 taps)  |                               *
  67. *                           --------------                               *
  68. *                                                                        *
  69. *                   Figure 2. DSP56200 Configuration                     *
  70. *                                                                        *
  71. *                                                                        *
  72. *                                                                        *
  73. *      ************************************************************      *
  74. *      *                                                          *      *
  75. *      *   This program originally available on the Motorola DSP  *      *
  76. *      *   bulletin board.  It is provided under a DISCLAMER OF   *      *
  77. *      *   WARRANTY available from  Motorola DSP Operation,       *      *
  78. *      *     6501 Wm. Cannon Drive W., Austin, Tx., 78735.        *      *
  79. *      *                                                          *      *
  80. *      ************************************************************      *
  81. *                                                                        *
  82. *                                                                        *
  83. *                                                                        *
  84. *      ************************************************************      *
  85. *      * Note on the Representation of Hex Numbers:               *      *
  86. *      *                                                          *      *
  87. *      *    In the programming language  "C",  hex numbers are    *      *
  88. *      *    represented by preceding the number with "0x". For    *      *
  89. *      *    example, e4 (hex) is represented in "C" as 0xe4.      *      *
  90. *      *                                                          *      *
  91. *      ************************************************************      *
  92. *                                                                        *
  93. \************************************************************************/
  94.  
  95.  
  96.  
  97.         /*** CONSTANTS ***/
  98.  
  99. #define   FOREVER     1         /* For infinite looping */
  100.  
  101.  
  102.  
  103. #define   X1_HI     0x0         /* Addresses (hex) of DSP56200 regs, bank 0 */
  104. #define   X1_LO     0x1
  105. #define   D_HI      0x2                     /* unused -Adaptive mode only */
  106. #define   D_LO      0x3                     /* unused -Adaptive mode only */
  107. #define   K_HI      0x4                     /* unused -Adaptive mode only */
  108. #define   K_LO      0x5                     /* unused -Adaptive mode only */
  109. #define   X2_HI     0x6
  110. #define   X2_LO     0x7
  111. #define   DATA_HI   0x8                     /* unused */
  112. #define   DATA_LO   0x9                     /* unused */
  113. #define   COEFF_HI  0xa
  114. #define   COEFF_MD  0xb
  115. #define   COEFF_LO  0xc
  116. #define   RAM_ADR   0xd
  117. #define   CONFIG    0xf
  118.  
  119. #define   OUTPUT3   0x0              /* Most  significant byte of 1st result */
  120. #define   OUTPUT2   0x1              /* Least significant byte of 1st result */
  121. #define   OUTPUT1   0x2              /* Most  significant byte of 2nd result */
  122. #define   OUTPUT0   0x3              /* Least significant byte of 2nd result */
  123. #define   LTAP1_HI  0x4                     /* unused */
  124. #define   LTAP1_LO  0x5                     /* unused */
  125. #define   LTAP2_HI  0x6                     /* unused */
  126. #define   LTAP2_LO  0x7                     /* unused */
  127.  
  128. #define   LEAKAGE   0x0         /* Addresses (hex) of DSP56200 regs, bank 1 */
  129. #define   FTL       0x1
  130.  
  131.  
  132.  
  133.                                 /* Values (hex) written to the DSP56200 regs */
  134. #define   CNFIG_0   0x50              /* Config reg: Selects bank 0 */
  135. #define   CNFIG_1   0x51              /* Config reg: Selects bank 1 */
  136. #define   FTL_VAL   0x06              /* Two filters, each with 7 taps */
  137.  
  138.  
  139.  
  140.         /* GLOBAL VARIABLES */
  141.  
  142. static int coeff[14][3] = {
  143.    { 0x08, 0x00, 0x00 },            /* 1st coeff of 1st filter (3 bytes) */
  144.    { 0x10, 0x00, 0x00 },            /* 2nd coeff ...                     */
  145.    { 0x18, 0x00, 0x00 },            /* 3rd coeff ...                     */
  146.    { 0x20, 0x00, 0x00 },            /* 4th coeff ...                     */
  147.    { 0x18, 0x00, 0x00 },            /* 5th coeff ...                     */
  148.    { 0x10, 0x00, 0x00 },            /* 6th coeff ...                     */
  149.    { 0x08, 0x00, 0x00 },            /* 7th coeff ...                     */
  150.    { 0x08, 0x00, 0x00 },            /* 1st coeff of 2nd filter (3 bytes) */
  151.    { 0x10, 0x00, 0x00 },            /* 2nd coeff ...                     */
  152.    { 0x18, 0x00, 0x00 },            /* 3rd coeff ...                     */
  153.    { 0x20, 0x00, 0x00 },            /* 4th coeff ...                     */
  154.    { 0x18, 0x00, 0x00 },            /* 5th coeff ...                     */
  155.    { 0x10, 0x00, 0x00 },            /* 6th coeff ...                     */
  156.    { 0x08, 0x00, 0x00 }             /* 7th coeff ...                     */
  157. };                           /*  This two-dimensional array holds the 14    */
  158.                              /*  coefficients required for the two FIR      */
  159.                              /*  filters (each coeff is three bytes long).  */
  160.                              /*  Note that the coeffs of the 1st filter     */
  161.                              /*  don't have to be the same as those of the  */
  162.                              /*  2nd filter, but in this case they are the  */
  163.                              /*  same. The coefficients would typically be  */
  164.                              /*  stored in a ROM in an actual setup.        */
  165.  
  166.  
  167.  
  168.         /*** MAIN PROGRAM ***/
  169.  
  170. main()   {
  171.  
  172.         /********************************************************************\
  173.         *                                                                    *
  174.         *   This program is an example of the software used by a host        *
  175.         *   processor to service a DSP56200 configured in the Dual FIR       *
  176.         *   Filter mode.  Three functions are performed:                     *
  177.         *                                                                    *
  178.         *         1. Initialize User's System and Configure the DSP56200.    *
  179.         *         2. Initialize the Coeff and Data RAMs of the DSP56200.     *
  180.         *         3. Run the Dual FIR Filters in a real-time environment.    *
  181.         *                                                                    *
  182.         *   Things to watch for when setting up the filtering system:        *
  183.         *                                                                    *
  184.         *         - There must be NO GLITCHES on the DSP56200's START pin.   *
  185.         *         - If codecs are used for the A/D or D/A conversion, see    *
  186.         *              comments in the routines "send_da()"and "get_ad()".   *
  187.         *         - If offset binary A/Ds or D/As are used, see comments     *
  188.         *              in the subroutines "send_da()" and "get_ad()".        *
  189.         *         - Coefficients must be correctly selected so that there    *
  190.         *              is no overflow (see box below).                       *
  191.         *                                                                    *
  192.         *      ********************************************************      *
  193.         *      * Preventing Overflow:                                 *      *
  194.         *      *                                                      *      *
  195.         *      *    All FIR filters are subject to overflow, and it   *      *
  196.         *      *    is important that the filter coefficients are     *      *
  197.         *      *    carefully selected to prevent overflow.  For the  *      *
  198.         *      *    DSP56200, overflow occurs when the right side of  *      *
  199.         *      *    equation (1) has a magnitude greater than 1.0:    *      *
  200.         *      *                                                      *      *
  201.         *      *                    N-1                               *      *
  202.         *      *                    __                                *      *
  203.         *      *                    \                                 *      *
  204.         *      *          y(n)  =   /_   h(i) * x(n-i)        (1)     *      *
  205.         *      *                   i = 0                              *      *
  206.         *      *                                                      *      *
  207.         *      *    N represents the number of filter taps (N = 7     *      *
  208.         *      *    in this program), and h(i) represents the "ith"   *      *
  209.         *      *    filter coefficient.  Both h(i) and x(n-i) are     *      *
  210.         *      *    signed, fractional numbers  in the DSP56200's     *      *
  211.         *      *    data format.                                      *      *
  212.         *      *                                                      *      *
  213.         *      *    If there is a possibility of overflow with a set  *      *
  214.         *      *    of filter coefficients, then all coefficients     *      *
  215.         *      *    must be scaled by a constant.  The DSP56200's     *      *
  216.         *      *    24 bit coefficients allow plenty of room for      *      *
  217.         *      *    scaling. If 12 bit input data samples are used in *      *
  218.         *      *    a system, the potential for overflow is greatly   *      *
  219.         *      *    reduced if the samples are sign-extended by four  *      *
  220.         *      *    bits before sending them to the DSP56200.         *      *
  221.         *      *                                                      *      *
  222.         *      ********************************************************      *
  223.         *                                                                    *
  224.         *                                                                    *
  225.         *   Note: The program assumes that the variable type "int" is at     *
  226.         *         least 16 bits wide.                                        *
  227.         *                                                                    *
  228.         \********************************************************************/
  229.  
  230.  
  231.  
  232.         /* Program Declarations */
  233.  
  234.            int tap;               /* filter tap number, used to load coeffs */
  235.  
  236.  
  237.  
  238.         /* Initialize System */
  239.  
  240.            /*   Here the user first initializes any other components of     */
  241.            /*   the filtering system which require initialization.  The     */
  242.            /*   DSP56200 is then initialized using the program code below.  */
  243.  
  244.  
  245.  
  246.         /* Reset and Configure the DSP56200 */
  247.  
  248.            wait_for_start();               /* This is done to synchronize   */
  249.                                            /* the program up to the system. */
  250.                                            /* Ensures that no writes occur  */
  251.                                            /* when the DSP56200's START pin */
  252.                                            /* receives a rising edge.       */
  253.  
  254.            wrbyte(CNFIG_1, CONFIG);        /* Configuration:                */
  255.                                            /*    - Dual FIR Filters         */
  256.                                            /*    - Not Cascaded             */
  257.                                            /*    - 16 Bit Rounding          */
  258.                                            /*    - DC Tap Disabled          */
  259.                                            /*    - Register Bank 1 Selected */
  260.            wrbyte(FTL_VAL, FTL);           /* Writing this reg also resets   */
  261.                                            /*    the chip at the beginning   */
  262.                                            /*    of the next sample period,  */
  263.                                            /*    which destroys any previous */
  264.                                            /*    contents of the Data RAM.   */
  265.  
  266.            wrbyte(CNFIG_0, CONFIG);        /* Switch to register bank 0 */
  267.  
  268.  
  269.  
  270.         /* Initialize the DSP56200's Coefficient and Data RAMS */
  271.  
  272.               wrbyte(0, X1_HI);       /* clears Data RAM when loading coeffs */
  273.               wrbyte(0, X1_LO);
  274.  
  275.               /* Presently for initialization, there are eleven writes   */
  276.               /* which the host processor must  perform in one sample    */
  277.               /* period.  If all these writes cannot be performed in one */
  278.               /* sample period, a call to the routine "wait_for_start()" */
  279.               /* can be inserted here,  and will reduce the number of    */
  280.               /* writes down to a maximum of six in one sample period.   */
  281.  
  282.               wrbyte(0, X2_HI);
  283.               wrbyte(0, X2_LO);
  284.  
  285.               wrbyte(coeff[0][0], COEFF_HI);         /* 1st coeff of 1st FIR */
  286.               wrbyte(coeff[0][1], COEFF_MD);
  287.               wrbyte(coeff[0][2], COEFF_LO);
  288.  
  289.               wrbyte(0, RAM_ADR);            /* autoincrements w/ each START */
  290.  
  291.               for (tap=1; tap<=(1 + 2*FTL_VAL); tap=tap+1)   {
  292.  
  293.                  wait_for_start();
  294.  
  295.                  wrbyte(coeff[tap][0], COEFF_HI);
  296.                  wrbyte(coeff[tap][1], COEFF_MD);
  297.                  wrbyte(coeff[tap][2], COEFF_LO);
  298.                                      /*  Note that the Data RAM is cleared   */
  299.                                      /*  since the DSP56200's X1 and X2 regs */
  300.                                      /*  are set to "0", resulting in "0"s   */
  301.                                      /*  being "shifted" into the filter's   */
  302.                                      /*  Data RAM (delay line) every sample  */
  303.                                      /*  period.                             */
  304.               }
  305.  
  306.  
  307.  
  308.         /* Run the Filters in Real-time */
  309.  
  310.               prealtime();
  311. }
  312.  
  313.  
  314.  
  315.         /*** SUBROUTINES ***/
  316.  
  317.  
  318.  
  319.         /* PREALTIME */
  320.  
  321. prealtime()
  322. {
  323.         /****************************************************************\
  324.         *                                                                *
  325.         *   This routine performs the I/O servicing required when the    *
  326.         *   DSP56200 is processing real-time samples.  Every sample      *
  327.         *   period (signified by the reception of a rising edge on the   *
  328.         *   DSP56200's START pin), the host processor sends two new      *
  329.         *   samples to the DSP56200, and reads out two results from      *
  330.         *   the DSP56200.                                                *
  331.         *                                                                *
  332.         *   This routine is used only in polled I/O systems.             *
  333.         *                                                                *
  334.         *   Note: The routine assumes that the variable type "int" is    *
  335.         *         at least 16 bits wide.                                 *
  336.         *                                                                *
  337.         *   Also: It is important that execution of the code inside the  *
  338.         *         while loop completes before the next sample period     *
  339.         *         begins.  This guarantees that the start of the next    *
  340.         *         sample period is never missed because the program will *
  341.         *         then be in the subroutine "wait_for_start()", polling  *
  342.         *         for the rising edge of the START signal.               *
  343.         *                                                                *
  344.         \****************************************************************/
  345.  
  346.  
  347.  
  348.         /* Subroutine Declarations */
  349.            int x1, x2, out;                       /* see Figure 2 */
  350.  
  351.  
  352.  
  353.         while (FOREVER)   {                       /* infinite loop */
  354.  
  355.            /* Poll for Reception of the START signal */
  356.               wait_for_start();
  357.  
  358.            /* Host Now Services the DSP56200 Since START Has Been Received */
  359.            
  360.               /* Read the New Samples from the A/Ds and Write to the DSP56200 */
  361.  
  362.                  x1 = get_ad(1);
  363.                  x2 = get_ad(2);
  364.  
  365.                  wrbyte((x1>>8) & 0x0ff, X1_HI);      /* writes upper byte */
  366.                  wrbyte( x1     & 0x0ff, X1_LO);      /* writes lower byte */
  367.                  wrbyte((x2>>8) & 0x0ff, X2_HI);      /* writes upper byte */
  368.                  wrbyte( x2     & 0x0ff, X2_LO);      /* writes lower byte */
  369.  
  370.               /* Read the Results from the 56200 and Write to the D/As */
  371.    
  372.                  out = rdbyte(OUTPUT3);
  373.                  out = out << 8;                      /* move to upper byte */
  374.                  out = out + (0x0ff & rdbyte(OUTPUT2));
  375.                  send_da(out,1);
  376.  
  377.                  out = rdbyte(OUTPUT1);
  378.                  out = out << 8;                      /* move to upper byte */
  379.                  out = out + (0x0ff & rdbyte(OUTPUT0));
  380.                  send_da(out,2);
  381.         }
  382. }
  383.  
  384.  
  385.  
  386.         /* WRBYTE */
  387.  
  388. wrbyte(val,adr)
  389. int val, adr;
  390. {
  391.         /**************************************************************\
  392.         *                                                              *
  393.         *   This subroutine writes one byte to the DSP56200 register   *
  394.         *   specified by "adr".                                        *
  395.         *   Note that the correct register bank has already been       *
  396.         *   selected (defined by the LSB of the Configuration reg).    *
  397.         *                                                              *
  398.         *   This subroutine could be defined as a macro for faster     *
  399.         *   execution.                                                 *
  400.         *                                                              *
  401.         *   Inputs:                                                    *
  402.         *      val  = bytewide value to be written to the DSP56200     *
  403.         *      adr  = address of the DSP56200 register to be written   *
  404.         *                                                              *
  405.         \**************************************************************/
  406.  
  407.         /* Actual program code depends on the user's system. */
  408. }
  409.  
  410.  
  411.  
  412.         /* RDBYTE */
  413.  
  414. rdbyte(adr)
  415. int adr;
  416. {
  417.         /**************************************************************\
  418.         *                                                              *
  419.         *  This subroutine reads one byte from the DSP56200 register   *
  420.         *  specified by "adr".                                         *
  421.         *  Note that the correct register bank has already been        *
  422.         *  selected (defined by the LSB of the Configuration reg).     *
  423.         *                                                              *
  424.         *  This subroutine could be defined as a macro for faster      *
  425.         *   execution.                                                 *
  426.         *                                                              *
  427.         *   Inputs:                                                    *
  428.         *      adr  = address of the DSP56200 register to be read      *
  429.         *                                                              *
  430.         *   Outputs:                                                   *
  431.         *      The routine returns the byte read from the DSP56200     *
  432.         *                                                              *
  433.         \**************************************************************/
  434.  
  435.         int valread;
  436.  
  437.         /* Actual program code depends on the user's system. */
  438.  
  439.         return(valread);
  440. }
  441.  
  442.  
  443.  
  444.         /* GET_AD */
  445.  
  446. get_ad(devnum)
  447. int devnum;
  448. {
  449.         /******************************************************************\
  450.         *                                                                  *
  451.         *   This subroutine returns a 16 bit value read from one of the    *
  452.         *   two A/D converters in the filtering system.                    *
  453.         *                                                                  *
  454.         *   Inputs:                                                        *
  455.         *      devnum = A/D Converter number:  1=1st FIR, 2=2nd FIR.       *
  456.         *                                                                  *
  457.         *   Outputs:                                                       *
  458.         *      The routine returns the value read from the selected A/D.   *
  459.         *                                                                  *
  460.         \******************************************************************/
  461.  
  462.         int ad_val;
  463.  
  464.         /* Actual program code depends on the user's system. */
  465.  
  466.         /*  If a codec is used for A/D conversion, the 8 bit companded  */
  467.         /*  sample must be converted into a 12 bit linear quantity and  */
  468.         /*  then sign extended to 16 bits.                              */
  469.  
  470.         /*  If the converter uses an offset binary format, it may be  */
  471.         /*  necessary to invert the sign bit (and any sign extension  */
  472.         /*  bits) to obtain a 2's complement number.                  */
  473.  
  474.         return(ad_val);
  475. }
  476.  
  477.  
  478.  
  479.         /* SEND_DA */
  480.  
  481. send_da(val,devnum)
  482. int val, devnum;
  483. {
  484.         /**************************************************************\
  485.         *                                                              *
  486.         *   This subroutine sends a value to a D/A converter where it  *
  487.         *   gets converted to an analog signal.                        *
  488.         *                                                              *
  489.         *   Inputs:                                                    *
  490.         *      val = value to be sent to the selected D/A converter    *
  491.         *      devnum = D/A Converter number:  1=1st FIR, 2=2nd FIR.   *
  492.         *                                                              *
  493.         \**************************************************************/
  494.  
  495.         /* Actual program code depends on the user's system. */
  496.  
  497.         /*  If a codec is used for D/A conversion, the 16 bit linear   */
  498.         /*  sample must be converted into a 8 bit companded quantity.  */
  499.  
  500.         /*  If the converter uses an offset binary format, it may be  */
  501.         /*  necessary to invert the sign bit (and any sign extension  */
  502.         /*  bits) to obtain a number in offset binary format.         */
  503. }
  504.  
  505.  
  506.  
  507.         /* WAIT_FOR_START */
  508.  
  509. wait_for_start()
  510. {
  511.         /********************************************************************\
  512.         *                                                                    *
  513.         *   This routine polls a general purpose input pin for a "1",        *
  514.         *   which indicates that a rising edge has arrived at the START pin  *
  515.         *   of the DSP56200 and that new samples are ready to be processed.  *
  516.         *                                                                    *
  517.         *   Note: It may be necessary to verify that the START signal has    *
  518.         *         returned to a "0" before polling for a "1".                *
  519.         *                                                                    *
  520.         *   Note: It is important that the program has completed other       *
  521.         *         processing and is waiting in this loop when the START      *
  522.         *         signal arrives so that no samples are lost.                *
  523.         *                                                                    *
  524.         \********************************************************************/
  525.  
  526.         int pin;
  527.  
  528.         pin = get_pin();
  529.  
  530.         while (pin == 0);                /* loops until "1" found on pin */
  531.            pin = get_pin();
  532. }
  533.  
  534.  
  535.  
  536.         /* GET_PIN */
  537.  
  538. get_pin()
  539. {
  540.         /*****************************************************************\
  541.         *                                                                 *
  542.         *   Returns the value read (0 or 1) from a general purpose input  *
  543.         *   pin which is tied directly to the DSP56200's START pin.       *
  544.         *                                                                 *
  545.         \*****************************************************************/
  546.         
  547.         /* Actual program code depends on the user's system. */
  548. }
  549.